package com.ibeeking.found.open.b.rest.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaUserService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import com.ibeeking.found.common.constants.WxOpenServiceTypeConstant;
import com.ibeeking.found.common.entity.DictDTO;
import com.ibeeking.found.common.entity.open.*;
import com.ibeeking.found.common.enums.DictTypeEnum;
import com.ibeeking.found.common.enums.OpenApiConfigEnum;
import com.ibeeking.found.common.enums.WxOpenAppTypeEnum;
import com.ibeeking.found.common.response.ResponseCodeEnum;
import com.ibeeking.found.common.utils.DataUtils;
import com.ibeeking.found.common.utils.UrlUtils;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.gmc.global.api.feign.GlobalDictFeignClient;
import com.ibeeking.gmc.global.api.feign.GlobalOpenFeignClient;
import com.ibeeking.found.open.api.common.param.OpenAuthCancelParam;
import com.ibeeking.found.open.api.common.param.OpenAuthParam;
import com.ibeeking.found.open.api.feign.GlobalOpenAuthFeignClient;
import com.ibeeking.found.open.api.feign.OpenFileFeignClient;
import com.ibeeking.found.open.b.rest.service.IOpenService;
import com.ibeeking.found.open.b.rest.service.IWxOpenEventService;
import com.ibeeking.found.open.service.common.constants.RedisKeyConstant;
import com.ibeeking.found.open.service.common.param.QueryOpenAuthInfoParam;
import com.ibeeking.found.open.service.common.param.WxUserInfoEncryptedParam;
import com.ibeeking.found.open.service.common.vo.*;
import com.ibeeking.found.open.service.config.OpenAuthCallBackConfig;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.file.oss.dto.OssPolicyDto;
import com.ibeeking.nematos.log.utils.LogUtils;
import com.ibeeking.nematos.redis.utils.RedisUtils;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.data.StringUtils;
import com.ibeeking.nematos.utils.file.FileUtils;
import com.ibeeking.nematos.utils.json.JsonUtils;
import com.ibeeking.nematos.utils.result.ResponseResult;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutTextMessage;
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.open.api.*;
import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo;
import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizerInfo;
import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage;
import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult;
import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult;
import me.chanjar.weixin.open.util.WxOpenCryptUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName WxOpenEventServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-06-18 12:21
 **/
@Service("wxOpenEventServiceImpl")
public class WxOpenEventServiceImpl implements IWxOpenEventService {
    private static final Logger log = LoggerFactory.getLogger(WxOpenEventServiceImpl.class);

    private static final Map<String, WxMpMessageRouter> wxOpenMpMessageRouterMap = new Hashtable();
    //2分钟
    private static final Long TIME = 30 * 60 *1000L;

    @Resource
    private IOpenService openServiceImpl;

    @Resource
    private GlobalOpenAuthFeignClient globalOpenAuthFeignClient;

    @Resource
    private GlobalOpenFeignClient globalOpenFeignClient;

    @Resource
    private GlobalDictFeignClient globalOpenDictFeignClient;

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private OpenFileFeignClient openFileFeignClient;

    @Resource
    private OpenAuthCallBackConfig openAuthCallBackConfig;

    @Override
    public String authTicket(String componentAppId, String data, String timestamp, String nonce, String signature, String encType, String msgSignature) {
        WxOpenService wxOpenService = openServiceImpl.getDefaultWxOpenService();
        WxOpenComponentService wxOpenComponentService = wxOpenService.getWxOpenComponentService();
        if(wxOpenComponentService == null) throw new BusinessException("can't WxOpenComponentService instance!");
        WxOpenConfigStorage wxOpenConfigStorage = wxOpenService.getWxOpenConfigStorage();

        // 校验签名
        checkSign(wxOpenService, "", encType, timestamp, nonce, signature);

       // aes加密的消息
        WxOpenXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedXml(data, wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature);

        String out = null;
        try {
            out = wxOpenComponentService.route(inMessage);

            OpenConfigDTO wxOpenConfigDTO = queryWxOpenConfigOfWxOpen();
            //LogUtils.info("=========OpenConfigDTO:{}============",JsonUtils.toJsonStr(wxOpenConfigDTO));
            if (null == wxOpenConfigDTO) {
                throw new BusinessException("无法获取开发平台参数信息");
            }

            if("component_verify_ticket".equals(inMessage.getInfoType())) {
                String newComponentVerifyTicket = inMessage.getComponentVerifyTicket();
                checkAndUpdateComponentAccessToken(componentAppId, wxOpenService, newComponentVerifyTicket, timestamp, nonce, signature);
                checkAndUpdateAuthorizeAccessToken(componentAppId, wxOpenService,inMessage.getAuthorizationCode(), timestamp, nonce, signature);
            }else if (StringUtils.equalsAnyIgnoreCase(inMessage.getInfoType(), "authorized", "updateauthorized")) {
                WxOpenAuthorizerInfoResult authorizerInfoResult = wxOpenComponentService.getAuthorizerInfo(inMessage.getAuthorizerAppid());

                wxOpenConfigStorage.autoRefreshToken();
                OpenAuthParam param = new OpenAuthParam();
                OpenAuthOfExtend openAuthOfExtend = new OpenAuthOfExtend();
                param.setConfigType(wxOpenConfigDTO.getType());
                param.setConfigSubType(wxOpenConfigDTO.getSubType());
                param.setOpenId(wxOpenConfigDTO.getId());
                param.setOpenAppId(wxOpenConfigDTO.getOpenAppId());
                param.setComponentAppId(componentAppId);
                param.setAppId(inMessage.getAuthorizerAppid());
                param.setComponentAppSecret(wxOpenConfigStorage.getComponentAppSecret());
                WxOpenAuthorizationInfo wxOpenAuthorizationInfo = authorizerInfoResult.getAuthorizationInfo();
                if(StringUtils.isEmpty(wxOpenAuthorizationInfo.getAuthorizerAccessToken())){
                    WxOpenQueryAuthResult queryAuthResult = wxOpenComponentService.getQueryAuth(inMessage.getAuthorizationCode());
                    if (queryAuthResult == null || queryAuthResult.getAuthorizationInfo() == null || StringUtils.isBlank(queryAuthResult.getAuthorizationInfo().getAuthorizerAppid())) {
                        DataUtils.trueThrowException(true, "获取微信授权信息失败");
                    }
                    wxOpenAuthorizationInfo = queryAuthResult.getAuthorizationInfo();
                }
                String authorizerAppid = wxOpenAuthorizationInfo.getAuthorizerAppid();
                String authorizerRefreshTokenKey = RedisKeyConstant.OPEN_AUTHORIZED_REFRESH_TOKEN.concat(":").concat(componentAppId).concat(":").concat(authorizerAppid);
                String authorizerAccessTokenKey = RedisKeyConstant.OPEN_AUTHORIZED_ACCESS_TOKEN.concat(":").concat(componentAppId).concat(":").concat(authorizerAppid);
                redisUtils.set(authorizerRefreshTokenKey, wxOpenAuthorizationInfo.getAuthorizerRefreshToken());
                redisUtils.set(authorizerAccessTokenKey, wxOpenAuthorizationInfo.getAuthorizerAccessToken());
                WxOpenAuthorizerInfo authorizerInfo = authorizerInfoResult.getAuthorizerInfo();
                WxOpenAuthorizerInfo.MiniProgramInfo miniProgramInfo = authorizerInfo.getMiniProgramInfo();
                Integer appType = null == miniProgramInfo ? WxOpenServiceTypeConstant.APPID_TYPE_MP : WxOpenServiceTypeConstant.APPID_TYPE_MINI;
                param.setAppType(appType);
                String tenantIdKey = "tenant:".concat(componentAppId).concat(":").concat(appType.toString());
                Object ObjTenantId = redisUtils.get(tenantIdKey);
                if(ObjTenantId !=null){
                    String tenantId = ObjTenantId.toString();
                    param.setTenantId(Long.valueOf(tenantId));
                    redisUtils.del(tenantIdKey);
                }
                OpenAuthOfWxOpen openAuthOfWxOpen = new OpenAuthOfWxOpen();
                openAuthOfWxOpen.setTimestamp(timestamp);
                openAuthOfWxOpen.setNonceStr(nonce);
                openAuthOfWxOpen.setSignature(signature);
                openAuthOfWxOpen.setPreAuthCode(inMessage.getPreAuthCode());
                openAuthOfWxOpen.setAuthorizationCode(inMessage.getAuthorizationCode());
                openAuthOfWxOpen.setAuthorizationCodeExpiredTime(inMessage.getAuthorizationCodeExpiredTime());
                openAuthOfWxOpen.setNickName(authorizerInfo.getNickName());
                openAuthOfWxOpen.setHeadImg(authorizerInfo.getHeadImg());

                openAuthOfWxOpen.setComponentVerifyTicket(wxOpenConfigStorage.getComponentVerifyTicket());
                openAuthOfWxOpen.setComponentAccessToken(wxOpenConfigStorage.getComponentAccessToken());
                openAuthOfWxOpen.setAuthorizerAccessToken(wxOpenAuthorizationInfo.getAuthorizerAccessToken());
                openAuthOfWxOpen.setAuthorizerRefreshToken(wxOpenAuthorizationInfo.getAuthorizerRefreshToken());
                openAuthOfWxOpen.setExpireTime(wxOpenAuthorizationInfo.getExpiresIn());
                openAuthOfWxOpen.setServiceTypeInfo(authorizerInfo.getServiceTypeInfo());
                openAuthOfWxOpen.setVerifyTypeInfo(authorizerInfo.getVerifyTypeInfo());
                openAuthOfWxOpen.setOriginalId(authorizerInfo.getUserName());
                openAuthOfWxOpen.setPrincipalName(authorizerInfo.getPrincipalName());
                openAuthOfWxOpen.setIntroduction(authorizerInfo.getSignature());
                openAuthOfWxOpen.setAlias(authorizerInfo.getAlias());
                String qrCodeUrl = authorizerInfo.getQrcodeUrl();
                if(StringUtils.isNotEmpty(qrCodeUrl)){
                    String uploadQrCodeUrl = uploadQrCode(authorizerAppid, authorizerInfo.getQrcodeUrl());
                    String qeCodeImgFileName = UrlUtils.removeUrlDomainName(uploadQrCodeUrl);
                    openAuthOfWxOpen.setQrcodeUrl(qeCodeImgFileName);
                }
                Map<String, Integer> businessInfo = authorizerInfo.getBusinessInfo();
                openAuthOfWxOpen.setOpenStore(businessInfo.get("open_store"));
                openAuthOfWxOpen.setOpenScan(businessInfo.get("open_scan"));
                openAuthOfWxOpen.setOpenPay(businessInfo.get("open_pay"));
                openAuthOfWxOpen.setOpenCard(businessInfo.get("open_card"));
                openAuthOfWxOpen.setOpenShake(businessInfo.get("open_shake"));
                openAuthOfWxOpen.setVisitStatus(null == miniProgramInfo ? 1 : miniProgramInfo.getVisitStatus());
                // 如果是公众号授权，miniProgramInfo为空
                if (null != miniProgramInfo) {
                    OpenAuthOfWxOpenMaProgram program = new OpenAuthOfWxOpenMaProgram();
                    OpenAuthOfWxOpenMaProgramNetwork programNetwork = new OpenAuthOfWxOpenMaProgramNetwork();
                    WxOpenAuthorizerInfo.MiniProgramInfo.Network network = miniProgramInfo.getNetwork();
                    programNetwork.setRequestDomain(network.getRequestDomain());
                    programNetwork.setWsRequestDomain(network.getWsRequestDomain());
                    programNetwork.setUploadDomain(network.getUploadDomain());
                    programNetwork.setDownloadDomain(network.getDownloadDomain());
                    programNetwork.setBizDomain(network.getBizDomain());
                    program.setNetwork(programNetwork);
                    List<WxOpenAuthorizerInfo.MiniProgramInfo.Category> categories = miniProgramInfo.getCategories();
                    List<OpenAuthOfWxOpenMaProgramCategory> wxOpenAuthProgramCategories = JsonUtils.jsonToList(categories, OpenAuthOfWxOpenMaProgramCategory.class);
                    program.setCategories(wxOpenAuthProgramCategories);
                    openAuthOfWxOpen.setProgramParam(program);
                    WxOpenMaService wxOpenMaService = wxOpenComponentService.getWxMaServiceByAppid(authorizerAppid);
                    if(null != wxOpenMaService) {
                        WxMaConfig wxMaConfig = wxOpenMaService.getWxMaConfig();
                        if (null != wxMaConfig) {
                            String appSecret = wxOpenConfigStorage.getWxMaConfig(authorizerAppid).getSecret();
                            if(StringUtils.isNotEmpty(appSecret))
                                param.setAppSecret(appSecret);
                            else
                                param.setAppSecret(wxMaConfig.getSecret());
                            param.setAppToken(wxMaConfig.getToken());
                            param.setAppAesKey(wxMaConfig.getAesKey());
                        }
                    }
                }else{
                    WxOpenMpService wxOpenMpService = wxOpenComponentService.getWxMpServiceByAppid(authorizerAppid);
                    if(null != wxOpenMpService) {
                        WxMpConfigStorage wxMpConfigStorage = wxOpenMpService.getWxMpConfigStorage();
                        if (null != wxMpConfigStorage) {
                            String appSecret = wxOpenConfigStorage.getWxMpConfigStorage(authorizerAppid).getSecret();
                            if(StringUtils.isNotEmpty(appSecret))
                                param.setAppSecret(appSecret);
                            else
                                param.setAppSecret(wxMpConfigStorage.getSecret());
                            param.setAppToken(wxMpConfigStorage.getToken());
                            param.setAppAesKey(wxMpConfigStorage.getAesKey());
                        }
                    }
                }
                if(Collections3.isNotEmpty(wxOpenAuthorizationInfo.getFuncInfo())) {
                    openAuthOfWxOpen.setFuncscopeCategorys(wxOpenAuthorizationInfo.getFuncInfo());
                }
                openAuthOfExtend.setOpenAuthOfWxOpen(openAuthOfWxOpen);
                param.setOpenAuthOfExtend(openAuthOfExtend);
                //LogUtils.info("更新开放平台授权参数:{}", JSON.toJSONString(param));
                globalOpenAuthFeignClient.modifyAuth(param);
            } else if ("unauthorized".equals(inMessage.getInfoType())) {
                String authorizerAppid = inMessage.getAuthorizerAppid();
                OpenAuthCancelParam param = new OpenAuthCancelParam();
                param.setAppId(authorizerAppid);

                param.setOpenAppId(wxOpenConfigDTO.getOpenAppId());
                param.setComponentAppId(componentAppId);
                String openAuthoriseInfoKey = RedisKeyConstant.OPEN_AUTHORIZED_INFO.concat("_").concat(componentAppId).concat("_").concat(inMessage.getAuthorizerAppid());
                String authorizeRefreshTokenKey = RedisKeyConstant.OPEN_AUTHORIZED_REFRESH_TOKEN.concat("_").concat(componentAppId).concat("_").concat(authorizerAppid);
                String authorizeAccessTokenKey = RedisKeyConstant.OPEN_AUTHORIZED_ACCESS_TOKEN.concat("_").concat(componentAppId).concat("_").concat(authorizerAppid);
                redisUtils.del(openAuthoriseInfoKey);
                redisUtils.del(authorizeRefreshTokenKey);
                redisUtils.del(authorizeAccessTokenKey);
                globalOpenAuthFeignClient.cancelAuth(param);
            }
        } catch (WxErrorException e) {
            LogUtils.error("开放平台授权事件更新global数据 出错:{}" ,e);
            throw new BusinessException(ResponseCodeEnum.FAIL.getMsg(), e);
        }
        return out;
    }

    @Override
    public Object msgEvent(String componentAppId, String openid, String data, String timestamp, String nonce, String signature, String encType, String msgSignature, HttpServletResponse httpServletResponse) {
        WxOpenService wxOpenService = openServiceImpl.getWxOpenService(componentAppId);
        if(wxOpenService == null) throw new BusinessException("can't WxOpenService instance!");
        checkSign(wxOpenService, openid, encType, timestamp, nonce, signature);

        String out = null;
        // aes加密的消息
        WxMpXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedMpXml(data, wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature);
        LogUtils.info("\n WxOpen callBack msgEvent:{} \n", JsonUtils.toJsonStr(inMessage));
        WxMpXmlOutMessage outMessage = getWxMpMessageRouterByAppid(openid, componentAppId).route(inMessage);
        if (outMessage != null) {
            try {
                httpServletResponse.getWriter().write(outMessage.toEncryptedXml(wxOpenService.getWxOpenConfigStorage().getWxMpConfigStorage(componentAppId)));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 全网发布测试用例
        if (StringUtils.equalsAnyIgnoreCase(componentAppId, "wxd101a85aa106f53e", "wx570bc396a51b8ff8")) {
            try {
                if (StringUtils.equals(inMessage.getMsgType(), "text")) {
                    if (StringUtils.equals(inMessage.getContent(), "TESTCOMPONENT_MSG_TYPE_TEXT")) {
                        out = new WxOpenCryptUtil(wxOpenService.getWxOpenConfigStorage()).encrypt(
                                WxMpXmlOutMessage.TEXT().content("TESTCOMPONENT_MSG_TYPE_TEXT_callback")
                                        .fromUser(inMessage.getToUser())
                                        .toUser(inMessage.getFromUser())
                                        .build()
                                        .toXml()
                        );
                    } else if (StringUtils.startsWith(inMessage.getContent(), "QUERY_AUTH_CODE:")) {
                        String msg = inMessage.getContent().replace("QUERY_AUTH_CODE:", "") + "_from_api";
                        WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(msg).toUser(inMessage.getFromUser()).build();
                        wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(componentAppId).getKefuService().sendKefuMessage(kefuMessage);
                    }
                } else if (StringUtils.equals(inMessage.getMsgType(), "event")) {
                    WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(inMessage.getEvent() + "from_callback").toUser(inMessage.getFromUser()).build();
                    wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(componentAppId).getKefuService().sendKefuMessage(kefuMessage);
                }
            } catch (WxErrorException e) {

            }
        }

        return out;
    }

    public WxMpMessageRouter getWxMpMessageRouterByAppid(String openid, String appId) {
        WxMpMessageRouter wxMpMessageRouter = wxOpenMpMessageRouterMap.get(appId);
        if (wxMpMessageRouter == null) {
            synchronized (wxOpenMpMessageRouterMap) {
                wxMpMessageRouter = wxOpenMpMessageRouterMap.get(appId);
                if (wxMpMessageRouter == null) {
                    wxMpMessageRouter = new WxMpMessageRouter(openServiceImpl.getWxOpenMpService(openid, appId));
                    wxOpenMpMessageRouterMap.put(appId, wxMpMessageRouter);
                    addTxtMsgRouter(appId, wxMpMessageRouter);
                    addEventRouter(appId, wxMpMessageRouter);
                }
            }
        }
        return wxMpMessageRouter;
    }

    private void addEventRouter(final String appId, WxMpMessageRouter wxMpMessageRouter) {
        WxMpMessageHandler handler = new WxMpMessageHandler() {
            public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context,
                                            WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
                WxMpXmlOutTextMessage m = null;
                // 订阅事件
                if (wxMessage.getEvent().equals(WxConsts.EventType.SUBSCRIBE)) {
                    if (wxMessage.getEventKey().startsWith("qrscene_") && wxMessage.getTicket() != null) {
                        String msg = wxMessage.getContent().replace("QUERY_AUTH_CODE:", "") + "_from_api";
                        WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(msg).toUser(wxMessage.getFromUser()).build();
                        wxMpService.getKefuService().sendKefuMessage(kefuMessage);
                    }
                } else if (wxMessage.getEvent().equals(WxConsts.EventType.SCAN)) {
                    // 扫码 用户已关注时的事件推送
                    if (wxMessage.getEventKey() != null || wxMessage.getTicket() != null) {
                        String msg = wxMessage.getContent().replace("QUERY_AUTH_CODE:", "") + "_from_api";
                        WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(msg).toUser(wxMessage.getFromUser()).build();
                        wxMpService.getKefuService().sendKefuMessage(kefuMessage);
                    }
                } else if (wxMessage.getEvent().equals(WxConsts.EventType.CLICK)) {// 自定义菜单点击事件
                    if (wxMessage.getEventKey() != null && !wxMessage.getEventKey().equals("")) {
                        System.out.println("事件KEY值，与自定义菜单接口中KEY值对应");
                    }
                } else if (wxMessage.getEvent().equals(WxConsts.EventType.VIEW)) {
                    System.out.println("点击菜单跳转链接时的事件推送");
                }
                return m;
            }
        };
        wxMpMessageRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).handler(handler).end();
    }

    private void addTxtMsgRouter(final String appId, WxMpMessageRouter wxMpMessageRouter) {
        WxMpMessageHandler handler = new WxMpMessageHandler() {
            public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context,
                                            WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
                WxMpXmlOutTextMessage m = null;
                String keys = wxMessage.getContent();
                if (keys.startsWith("xxxxx")&& wxMessage.getFromUser().equals("DSFGDFNMHJJHJ")) {
                    String msg = wxMessage.getContent().replace("QUERY_AUTH_CODE:", "") + "_from_api";
                    WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(msg).toUser(wxMessage.getFromUser()).build();
                    wxMpService.getKefuService().sendKefuMessage(kefuMessage);
                }
                return m;
            }
        };
        wxMpMessageRouter.rule().async(false).msgType(WxConsts.XmlMsgType.TEXT).handler(handler).end();
    }
    /**
     * 授权注册页面扫码授权   显示二维码
     *
     * @param request
     * @return
     * @throws Exception
     * @Author ibeeking
     */
    @Override
    public UrlVO getPreAuthUrl(HttpServletRequest request, Integer type) throws Exception {
        String tenantId = UserUtils.getTenantId();
        OpenConfigDTO openConfigDTO = queryWxOpenConfigOfWxOpen();
        String componentAppId = openConfigDTO.getComponentAppId();
        DataUtils.trueThrowException(StringUtils.isBlank(componentAppId), "系统异常:微信第三放平台appId为空!");
        String wxOpenAuthRedirectUrl = "";
        if (WxOpenServiceTypeConstant.APPID_TYPE_MINI.equals(type)) {
            wxOpenAuthRedirectUrl = openAuthCallBackConfig.getWxOpenMaAuthRedirectUrl();
        } else if (WxOpenServiceTypeConstant.APPID_TYPE_MP.equals(type)) {
            wxOpenAuthRedirectUrl = openAuthCallBackConfig.getWxOpenMpAuthRedirectUrl();
        }
        DataUtils.trueThrowException(StringUtils.isBlank(wxOpenAuthRedirectUrl), "微信第三方授权后的跳转页面尚未配置!");
        if(StringUtils.isNotEmpty(tenantId)){
            String key = "tenant:".concat(componentAppId).concat(":").concat(type.toString());
            redisUtils.set(key, tenantId);
        }
        wxOpenAuthRedirectUrl = wxOpenAuthRedirectUrl + "?componentAppId=" + componentAppId + "&type=" + type;
        WxOpenService wxOpenService = openServiceImpl.getWxOpenService(componentAppId);
        if(null == wxOpenService) throw new BusinessException("微信开放平台服务初始化还未完成，请稍候再试");
        WxOpenComponentService wxOpenComponentService = wxOpenService.getWxOpenComponentService();
        if(null == wxOpenComponentService) throw new BusinessException("微信开放平台服务初始化还未完成，请稍候再试");
        //LogUtils.info("wxOpenAuthRedirectUrl:{}", wxOpenAuthRedirectUrl);
        String url = wxOpenComponentService.getPreAuthUrl(wxOpenAuthRedirectUrl);
        return new UrlVO().setUrl(url);
    }

    @Override
    public OpenAuthVO queryOrUpdateOpenAuthInfo(QueryOpenAuthInfoParam param) throws Exception {
        String tenantId = param.getTenantId();
        String openAppId = param.getOpenAppId();
        String appId = param.getAppId();
        String componentAppId = param.getComponentAppId();
        String authCode = param.getAuthCode();
        String expiresIn = param.getExpiresIn();
        Integer serviceType =  param.getType();
        if(StringUtils.isEmpty(tenantId))
           tenantId = UserUtils.getTenantId();

        if(StringUtils.isEmpty(tenantId)){
            DataUtils.trueThrowException(true, "获取租户tenantId失败:" + tenantId);
        }

        OpenAuthDTO wxOpenAuthDTO = null;
        OpenAuthOfExtend openAuthOfExtend = null;
        try {
            if (StringUtils.isBlank(componentAppId)) {
                wxOpenAuthDTO = queryOpenAuthByTenantIdAndType(Long.valueOf(tenantId), OpenApiConfigEnum.OPEN_CONFIG_TYPE_WECHAT_OPEN.getCode(), WxOpenAppTypeEnum.WECHAT_OPEN_APP_TYPE_TP.getCode(), serviceType);
            } else {
                wxOpenAuthDTO = queryOpenAuthByTenantAndComponnetAppType(Long.valueOf(tenantId), componentAppId, serviceType);
            }
            //LogUtils.info("====wxOpenAuthDTO:{}====",JsonUtils.toJsonStr(wxOpenAuthDTO));
            if (null != wxOpenAuthDTO) {
                openAuthOfExtend = wxOpenAuthDTO.getOpenAuthOfExtend();
                OpenAuthOfWxOpen openAuthOfWxOpen = openAuthOfExtend.getOpenAuthOfWxOpen();
                if(openAuthOfWxOpen == null){
                    openAuthOfWxOpen = JsonUtils.fromJson(wxOpenAuthDTO.getExtendJson(), OpenAuthOfWxOpen.class);
                }
                OssPolicyDto ossPolicyDto = getOssPolicy();
                if (null != ossPolicyDto) {
                    String dnsHost = ossPolicyDto.getHost();
                    if (StringUtils.isNotEmpty(openAuthOfWxOpen.getQrcodeUrl())) {
                        openAuthOfWxOpen.setQrcodeUrl(dnsHost + "/" + openAuthOfWxOpen.getQrcodeUrl());
                        openAuthOfExtend.setOpenAuthOfWxOpen(openAuthOfWxOpen);
                    }
                }
            }
        }catch(Exception ex){
            LogUtils.error("读取授权信息出错:{}",ex.getMessage());
            wxOpenAuthDTO = new OpenAuthDTO();
            wxOpenAuthDTO.setTenantId(Long.valueOf(tenantId));
            wxOpenAuthDTO.setOpenAppId(openAppId);
            wxOpenAuthDTO.setComponentAppId(componentAppId);
            OpenAuthOfWxOpen  openAuthOfWxOpen = new OpenAuthOfWxOpen();
            openAuthOfExtend = new OpenAuthOfExtend();
            openAuthOfExtend.setOpenAuthOfWxOpen(openAuthOfWxOpen);
            wxOpenAuthDTO.setOpenAuthOfExtend(openAuthOfExtend);
        }
       // LogUtils.info("====wxOpenAuthDTO:{}====",JsonUtils.toJsonStr(wxOpenAuthDTO));
        OpenAuthVO openAuthVO = JsonUtils.fromJson(wxOpenAuthDTO, OpenAuthVO.class);
        if(openAuthOfExtend!=null) {
            openAuthVO.setOpenAuthOfExtend(openAuthOfExtend);
        }
        //LogUtils.info("====openAuthVO:{}====",JsonUtils.toJsonStr(openAuthVO));
        return openAuthVO;
    }

    @Override
    public List<WxOpenAuthFuncVO> queryWxOpenAuthFuncList(String appId) {
        List<WxOpenAuthFuncVO> wxOpenAuthFuncVO = new ArrayList<>();
        String tenantId = UserUtils.getTenantId();
        OpenAuthQuery query = new OpenAuthQuery();
        query.setTenantId(Long.valueOf(tenantId));
        query.setAppId(appId);
        ResponseResult<OpenAuthDTO> responseResult = globalOpenFeignClient.queryOpenAuthOne(query);
        DataUtils.trueThrowException(!ResponseCodeEnum.SUCCESS.getCode().equals(responseResult.getCode()), responseResult.getMsg());
        OpenAuthDTO openAuthDTO = responseResult.getData();
        if(openAuthDTO!=null){
            OpenAuthOfExtend openAuthOfExtend = openAuthDTO.getOpenAuthOfExtend();
            OpenAuthOfWxOpen openAuthOfWxOpen = openAuthOfExtend.getOpenAuthOfWxOpen();
            List<Integer> funcScope = openAuthOfWxOpen.getFuncscopeCategorys();
            ResponseResult<List<DictDTO>> dictDTOListResp  = globalOpenDictFeignClient.queryDictByType(DictTypeEnum.WX_OPEN_AUTH_FUNC_DESC.getValue());
            DataUtils.trueThrowException(!ResponseCodeEnum.SUCCESS.getCode().equals(dictDTOListResp.getCode()), dictDTOListResp.getMsg());
            List<DictDTO> dictDTOList = dictDTOListResp.getData();
            Map<Integer, DictDTO> dictDTOMap = Collections3.isNotEmpty(dictDTOList)?dictDTOList.stream().collect(Collectors.toMap(x -> Integer.valueOf(x.getValue()), x -> x, (o, n) -> n)):null;
            if(Collections3.isNotEmpty(funcScope)){
                funcScope.stream().forEach(d->{
                    DictDTO dictDTO = dictDTOMap!=null?dictDTOMap.get(d):null;
                    WxOpenAuthFuncVO funcVo = new WxOpenAuthFuncVO();
                    funcVo.setFuncscopeCategory(d);
                    funcVo.setFuncscopeCategoryName(dictDTO!=null?dictDTO.getLabel():"");
                    funcVo.setFuncscopeCategoryRemark(dictDTO!=null?dictDTO.getRemark():"");
                    wxOpenAuthFuncVO.add(funcVo);
                });
            }
        }
        if(Collections3.isNotEmpty(wxOpenAuthFuncVO)){
            return wxOpenAuthFuncVO;
        }else{
            return Collections3.emptyList();
        }
    }

    @Override
    public WxUserInfoDecryptedVO decryptWxUserInfo(WxUserInfoEncryptedParam param) {
        WxUserInfoDecryptedVO wxUserInfoVO = null;
        if(param == null) throw new BusinessException("获取用户信息参数空！");
        String tenantId = param.getTenantId();
        if(StringUtils.isEmpty(tenantId)) throw new BusinessException("获取tenantId为空！");
        String appId = param.getAppId();
        if(StringUtils.isEmpty(appId)) throw new BusinessException("获取appId为空！");
        String jsCode = param.getJsCode();
        if(StringUtils.isEmpty(jsCode)) throw new BusinessException("获取用户登录凭证Code为空！");
        try {
            OpenAuthDTO openAuthDTO = queryOpenAuthByTenantAndAppid(Long.valueOf(tenantId), appId);
            WxOpenMaService wxOpenMaService = openServiceImpl.getWxOpenMaService(openAuthDTO.getComponentAppId(), appId);
            if (wxOpenMaService == null) throw new BusinessException("can't get wxOpenMaService service!");
            WxMaUserService wxMaUserService = wxOpenMaService.getUserService();
            if (wxMaUserService == null) throw new BusinessException("can't get wxMaUserService service!");
            WxMaJscode2SessionResult jscode2SessionResult = wxMaUserService.getSessionInfo(jsCode);
            if(jscode2SessionResult!=null){
                String sessionKey = jscode2SessionResult.getSessionKey();
                String unionId = jscode2SessionResult.getUnionid();
                String openId = jscode2SessionResult.getOpenid();
                if(StringUtils.isNotEmpty(sessionKey)){
                    Boolean checkwxSignature = wxMaUserService.checkUserInfo(sessionKey, param.getRawData(), param.getSignature());
                    if(!checkwxSignature) throw new BusinessException("校验解密用户信息出错!");
                    WxMaUserInfo wxMaUserInfo = wxMaUserService.getUserInfo(sessionKey, param.getEncryptedData(), param.getIvStr());
                    if(wxMaUserInfo!=null){
                        wxUserInfoVO = BeanUtil.convertBean(wxMaUserInfo, WxUserInfoDecryptedVO.class);
                        wxUserInfoVO.setOpenId(openId);
                        wxUserInfoVO.setAppId(appId);
                        if(wxMaUserInfo.getWatermark()!=null){
                            wxUserInfoVO.setTimestamp(wxMaUserInfo.getWatermark().getTimestamp());
                        }
                    }
                }
            }
        }catch(WxErrorException ex){
            throw new BusinessException("获取用户解密信息失败",ex);
        }
        return wxUserInfoVO;
    }

    private OssPolicyDto getOssPolicy() {
        ResponseResult<OssPolicyDto> ossPolicyResult = openFileFeignClient.policy();
        DataUtils.trueThrowException(!ResponseCodeEnum.SUCCESS.getCode().equals(ossPolicyResult.getCode()), ossPolicyResult.getMsg());
        return ossPolicyResult.getData();
    }

    /**
     * 跟新授权Token
     *
     * @param wxOpenService
     * @param timestamp
     */
    private void checkAndUpdateComponentAccessToken(String componentAppId, WxOpenService wxOpenService , String componentVerifyTicket, String timestamp, String nonce, String signature){
        WxOpenComponentService wxOpenComponentService = wxOpenService.getWxOpenComponentService();
        if(wxOpenComponentService == null) throw new BusinessException("can't WxOpenComponentService service!");
        WxOpenConfigStorage wxOpenConfigStorage = wxOpenComponentService.getWxOpenConfigStorage();
        if(wxOpenConfigStorage == null) throw new BusinessException("can't wxOpenConfigStorage service!");
        if(wxOpenConfigStorage.isComponentAccessTokenExpired() || StringUtils.isNotEmpty(wxOpenConfigStorage.getComponentAccessToken())) {
            OpenConfigDTO wxOpenConfigDTO = openServiceImpl.queryWxOpenConfigByComponentAppId(componentAppId);
            //LogUtils.info("=========OpenConfigDTO:{}============",JsonUtils.toJsonStr(wxOpenConfigDTO));
            if (null == wxOpenConfigDTO) {
                throw new BusinessException("无法获取开发平台参数信息");
            }
            wxOpenConfigStorage.setComponentAppId(wxOpenConfigDTO.getComponentAppId());
            wxOpenConfigStorage.setComponentToken(wxOpenConfigDTO.getComponentMsgToken());
            wxOpenConfigStorage.setComponentAppSecret(wxOpenConfigDTO.getComponentSecret());
            wxOpenConfigStorage.setComponentAesKey(wxOpenConfigDTO.getComponentMsgAesKey());
            wxOpenConfigStorage.setComponentVerifyTicket(componentVerifyTicket);
            try {
                String componentAccessToken = wxOpenComponentService.getComponentAccessToken(true);
                wxOpenConfigStorage.updateComponentAccessToken(componentAccessToken,TIME.intValue());
                LogUtils.info("=========update ComponentAccessToken:{}============", componentAccessToken);
            }catch(WxErrorException ex){
                throw new BusinessException("更新component access token失败",ex);
            }
            //LogUtils.info("=========wxOpenConfigStorage:{}============",JsonUtils.toJsonStr(wxOpenConfigStorage));
        }
    }

    /**
     * 跟新授权Token
     *
     * @param wxOpenService
     * @param timestamp
     */
    private void checkAndUpdateAuthorizeAccessToken(String componentAppId, WxOpenService wxOpenService , String authorizationCode, String timestamp, String nonce, String signature){
        List<OpenAuthDTO> openAuthDTOS = queryOpenAuthListByComponentId(componentAppId);
        if(Collections3.isNotEmpty(openAuthDTOS)) {
            openAuthDTOS.stream().forEach(openAuthDTO -> {
                OpenAuthOfExtend openAuthOfExtend = openAuthDTO.getOpenAuthOfExtend();
                if(openAuthOfExtend == null){
                    String extendJson = openAuthDTO.getExtendJson();
                    openAuthOfExtend = JsonUtils.fromJson(extendJson, OpenAuthOfExtend.class);
                }
                OpenAuthOfWxOpen openAuthOfWxOpen = openAuthOfExtend.getOpenAuthOfWxOpen();

                String appId = openAuthDTO.getAppId();
                if(StringUtils.isEmpty(appId)) throw new BusinessException("checkAndUpdateAuthorizeAccessToken get Appid is null");
                String authorizerRefreshTokenKey = RedisKeyConstant.OPEN_AUTHORIZED_REFRESH_TOKEN.concat(":").concat(componentAppId).concat(":").concat(appId);
                String authorizerAccessTokenKey = RedisKeyConstant.OPEN_AUTHORIZED_ACCESS_TOKEN.concat(":").concat(componentAppId).concat(":").concat(appId);

                WxOpenComponentService wxOpenComponentService = wxOpenService.getWxOpenComponentService();
                WxOpenConfigStorage wxOpenConfigStorage = wxOpenComponentService.getWxOpenConfigStorage();

                String authorizerAccessToken = wxOpenConfigStorage.getAuthorizerAccessToken(appId);
                String jsapiTicket = wxOpenConfigStorage.getJsapiTicket(appId);
                LogUtils.info("=========old authorizerAccessToken:{}============", authorizerAccessToken);
                try {
                    WxOpenAuthorizerInfoResult authorizerInfoResult = wxOpenComponentService.getAuthorizerInfo(appId);
                    WxOpenAuthorizationInfo wxOpenAuthorizationInfo = authorizerInfoResult.getAuthorizationInfo();
                    if(StringUtils.isEmpty(authorizerAccessToken) || wxOpenConfigStorage.isAuthorizerAccessTokenExpired(appId)){
                        LogUtils.info("=========update wxOpenAuthorizationInfo:{}============", JsonUtils.toJsonStr(wxOpenAuthorizationInfo));
                        if(StringUtils.isNotEmpty(wxOpenAuthorizationInfo.getAuthorizerRefreshToken()))
                            wxOpenConfigStorage.setAuthorizerRefreshToken(appId, wxOpenAuthorizationInfo.getAuthorizerRefreshToken());
                        String newAuthorizerAccessToken = wxOpenAuthorizationInfo.getAuthorizerAccessToken();
                        if (StringUtils.isEmpty(newAuthorizerAccessToken)) {
                            newAuthorizerAccessToken = wxOpenComponentService.getAuthorizerAccessToken(appId,true);
                            LogUtils.info("=========request new authorizerAccessToken:{}============", newAuthorizerAccessToken);
                            if (StringUtils.isEmpty(newAuthorizerAccessToken)) {
                                WxOpenQueryAuthResult queryAuthResult = wxOpenComponentService.getQueryAuth(openAuthOfWxOpen.getAuthorizationCode());
                                LogUtils.info("=========update ueryAuth1:{}============", JsonUtils.toJsonStr(queryAuthResult));
                                if (queryAuthResult == null || queryAuthResult.getAuthorizationInfo() == null || StringUtils.isBlank(queryAuthResult.getAuthorizationInfo().getAuthorizerAppid())) {
                                    DataUtils.trueThrowException(true, "获取微信授权信息失败");
                                }
                                LogUtils.info("=========update ueryAuth:{}============", JsonUtils.toJsonStr(queryAuthResult));
                                wxOpenAuthorizationInfo = queryAuthResult.getAuthorizationInfo();
                            }
                        }
                        int expireTime = wxOpenAuthorizationInfo.getExpiresIn();
                        String newAuthorizerRefreshToken = wxOpenAuthorizationInfo.getAuthorizerRefreshToken();
                        if(StringUtils.isNotEmpty(newAuthorizerRefreshToken)) {
                            LogUtils.info("=========update AuthorizerRefreshToken:{}============", newAuthorizerRefreshToken);
                            wxOpenConfigStorage.updateAuthorizerRefreshToken(appId, newAuthorizerRefreshToken);
                            redisUtils.set(authorizerRefreshTokenKey, newAuthorizerRefreshToken);
                        }
                        if(StringUtils.isNotEmpty(newAuthorizerAccessToken)) {
                            LogUtils.info("=========update AuthorizerAccessToken:{}============", newAuthorizerAccessToken);
                            wxOpenConfigStorage.updateAuthorizerAccessToken(appId, newAuthorizerAccessToken, expireTime);
                            redisUtils.set(authorizerAccessTokenKey, newAuthorizerAccessToken);
                        }

                    }
                    LogUtils.info("=========update AuthParam:{}============", appId);
                    checkAndUpdateGlobalOpenAuthParam(componentAppId, wxOpenConfigStorage, wxOpenAuthorizationInfo, appId, timestamp, nonce, signature);
                }catch(WxErrorException ex){
                    throw new BusinessException("更新微信授权信息失败，{}", ex);
                }
            }
           );
        }
    }

    /**
     * 跟新授权Token
     *
     * @param wxOpenConfigStorage
     * @param timestamp
     */
    private void checkAndUpdateGlobalOpenAuthParam(String componentAppId, WxOpenConfigStorage wxOpenConfigStorage , WxOpenAuthorizationInfo wxOpenAuthorizationInfo, String appId, String timestamp, String nonce, String signature) {
        //更新global OpenAuth
        OpenAuthDTO wxOpenAuthDTO = queryOpenAuthByComponnetIdAndAppId(componentAppId, appId);
        //LogUtils.info("wxOpenAuthDTO:{}", JSON.toJSONString(wxOpenAuthDTO));
        if( null != wxOpenAuthDTO){
            OpenAuthOfExtend openAuthOfExtend = wxOpenAuthDTO.getOpenAuthOfExtend();
            if(openAuthOfExtend == null){
                String extendJson = wxOpenAuthDTO.getExtendJson();
                openAuthOfExtend = JsonUtils.fromJson(extendJson, OpenAuthOfExtend.class);
            }
            OpenAuthOfWxOpen openAuthOfWxOpen = openAuthOfExtend.getOpenAuthOfWxOpen();
            openAuthOfWxOpen.setTimestamp(timestamp);
            openAuthOfWxOpen.setNonceStr(nonce);
            openAuthOfWxOpen.setSignature(signature);
            if(openAuthOfWxOpen == null) throw new BusinessException("读取授权信息出错！");
            String componentAccessToken = wxOpenConfigStorage.getComponentAccessToken();
            String componentVerifyTicket  = wxOpenConfigStorage.getComponentVerifyTicket();
            String authorizerRefreshToken = wxOpenConfigStorage.getAuthorizerRefreshToken(appId);
            String authorizerAccessToken = wxOpenConfigStorage.getAuthorizerAccessToken(appId);

            if(!StringUtils.equalsAnyIgnoreCase(componentAccessToken, openAuthOfWxOpen.getComponentAccessToken()) ||
               !StringUtils.equalsAnyIgnoreCase(componentVerifyTicket, openAuthOfWxOpen.getComponentVerifyTicket()) ||
               !StringUtils.equalsAnyIgnoreCase(authorizerRefreshToken, openAuthOfWxOpen.getAuthorizerRefreshToken()) ||
               !StringUtils.equalsAnyIgnoreCase(authorizerAccessToken, openAuthOfWxOpen.getAuthorizerAccessToken())
            ) {
                OpenAuthParam openAuthParam = BeanUtil.convertBean(wxOpenAuthDTO, OpenAuthParam.class);
                openAuthParam.setConfigType(OpenApiConfigEnum.OPEN_CONFIG_TYPE_WECHAT_OPEN.getCode());
                openAuthParam.setConfigSubType(WxOpenAppTypeEnum.WECHAT_OPEN_APP_TYPE_TP.getCode());

                openAuthOfWxOpen.setAuthorizerAccessToken(authorizerAccessToken);
                openAuthOfWxOpen.setAuthorizerRefreshToken(authorizerRefreshToken);
                if (StringUtils.isNotEmpty(componentAccessToken))
                    openAuthOfWxOpen.setComponentAccessToken(componentAccessToken);
                if (StringUtils.isNotEmpty(componentVerifyTicket))
                    openAuthOfWxOpen.setComponentVerifyTicket(componentVerifyTicket);
                if(wxOpenAuthorizationInfo != null){
                    openAuthOfWxOpen.setFuncscopeCategorys(wxOpenAuthorizationInfo.getFuncInfo());
                }
                openAuthOfExtend.setOpenAuthOfWxOpen(openAuthOfWxOpen);
                openAuthParam.setOpenAuthOfExtend(openAuthOfExtend);
                //LogUtils.info("=========openAuthParam:{}============",JsonUtils.toJsonStr(openAuthParam));
                globalOpenAuthFeignClient.modifyAuth(openAuthParam);
            }
        }
    }

    private String uploadQrCode(String appId, String qrcodeUrl){
        if(StringUtils.isEmpty(qrcodeUrl)) return "";
        try {
            MultipartFile multipartFile = FileUtils.getMultipartFile(qrcodeUrl, appId.concat("_".concat("qrCodeImg.jpg")), "qrCodeImg");
            ResponseResult<String> responseResult = openFileFeignClient.uploadFile(multipartFile);

            DataUtils.trueThrowException(!ResponseCodeEnum.SUCCESS.getCode().equals(responseResult.getCode()), responseResult.getMsg());
            return responseResult.getData();

        }catch(IOException ex){
            throw new BusinessException("保存二维码图片文件出错！");
        }
    }
    /**
     * 数据验签
     *
     * @param wxOpenService
     * @param encType
     * @param timestamp
     * @param nonce
     * @param signature
     */
    private void checkSign(WxOpenService wxOpenService, String openId, String encType, String timestamp, String nonce, String signature) {

        WxOpenComponentService wxOpenComponentService = wxOpenService.getWxOpenComponentService();
        if(wxOpenComponentService == null){
            throw new IllegalArgumentException("获取组件wxOpenComponentService空指针！");
        }
        boolean checkSignature = wxOpenComponentService.checkSignature(timestamp, nonce, signature);

        if (!StringUtils.equalsIgnoreCase("aes", encType) || !checkSignature) {
            throw new IllegalArgumentException("非法请求，可能属于伪造的请求！");
        }
    }
    /**
     * @return
     * @Author ibeeking
     * 返回公众号授权信息
     */
    @Override
    public  OpenAuthViewVO queryOpenAuthViewByAllType(Long tenantId, Integer configType, Integer configSubType, Integer AppType){
        OpenAuthQuery query = new OpenAuthQuery();
        query.setTenantId(tenantId);
        query.setConfigType(configType);
        query.setConfigSubType(configSubType);
        query.setAppType(AppType);
        ResponseResult<OpenAuthDTO> responseResult = globalOpenFeignClient.queryOpenAuthOne(query);
        OpenAuthDTO openAuthDTO = responseResult.getData();
        if(openAuthDTO!=null){
            OpenAuthViewVO openAuthViewVO = BeanUtil.convertBean(openAuthDTO, OpenAuthViewVO.class);
            OpenAuthOfExtend openAuthOfExtend = openAuthDTO.getOpenAuthOfExtend();
            if(openAuthOfExtend!=null){
                if(configType==OpenApiConfigEnum.OPEN_CONFIG_TYPE_WECHAT_OPEN.getCode()){
                    if(configSubType == WxOpenAppTypeEnum.WECHAT_OPEN_APP_TYPE_TP.getCode()){
                        OpenAuthOfWxOpen openAuthOfWxOpen =  openAuthOfExtend.getOpenAuthOfWxOpen();
                        if(openAuthOfWxOpen!=null) {
                            openAuthViewVO.setName(openAuthOfWxOpen.getNickName());
                            openAuthViewVO.setPrincipalName(openAuthViewVO.getPrincipalName());
                            return openAuthViewVO;
                        }
                    }
                }
            }
        }
        return new OpenAuthViewVO();
    }

    @Override
    public  OpenAuthDTO queryOpenAuthByTenantIdAndType(Long tenantId,  Integer configType,  Integer configSubType, Integer appType) {
        OpenAuthQuery query = new OpenAuthQuery();
        query.setTenantId(tenantId);
        query.setConfigType(configType);
        query.setConfigSubType(configSubType);
        query.setAppType(appType);
        ResponseResult<OpenAuthDTO> responseResult = globalOpenFeignClient.queryOpenAuthOne(query);
        return responseResult.getData();
    }

    private List<OpenAuthDTO> queryOpenAuthListByComponentId(String componentAppId) {
        OpenAuthQuery query = new OpenAuthQuery();
        query.setComponentAppId(componentAppId);
        ResponseResult<List<OpenAuthDTO>> responseResult = globalOpenFeignClient.queryOpenAuthList(query);
        DataUtils.trueThrowException(!ResponseCodeEnum.SUCCESS.getCode().equals(responseResult.getCode()), responseResult.getMsg());
        return JsonUtils.jsonToList(responseResult.getData(), OpenAuthDTO.class);
    }

    private OpenAuthDTO queryOpenAuthByTenantAndComponnetAppType(Long tenantId, String componentAppId, Integer appType) {
        OpenAuthQuery query = new OpenAuthQuery();
        query.setTenantId(tenantId);
        query.setComponentAppId(componentAppId);
        query.setAppType(appType);
        ResponseResult<OpenAuthDTO> responseResult = globalOpenFeignClient.queryOpenAuthOne(query);
        DataUtils.trueThrowException(!ResponseCodeEnum.SUCCESS.getCode().equals(responseResult.getCode()), responseResult.getMsg());
        return responseResult.getData();
    }

    private OpenAuthDTO queryOpenAuthByTenantAndAppid(Long tenantId, String appId) {
        OpenAuthQuery query = new OpenAuthQuery();
        query.setTenantId(tenantId);
        query.setAppId(appId);
        ResponseResult<OpenAuthDTO> responseResult = globalOpenFeignClient.queryOpenAuthOne(query);
        DataUtils.trueThrowException(!ResponseCodeEnum.SUCCESS.getCode().equals(responseResult.getCode()), responseResult.getMsg());
        return responseResult.getData();
    }

    private OpenAuthDTO queryOpenAuthByComponnetIdAndAppId(String componentAppId, String appId) {
        OpenAuthQuery query = new OpenAuthQuery();
        query.setComponentAppId(componentAppId);
        query.setAppId(appId);
        ResponseResult<OpenAuthDTO> responseResult = globalOpenFeignClient.queryOpenAuthOne(query);
        DataUtils.trueThrowException(!ResponseCodeEnum.SUCCESS.getCode().equals(responseResult.getCode()), responseResult.getMsg());
        return responseResult.getData();
    }

    private OpenConfigDTO queryWxOpenConfigOfWxOpen() {
        OpenConfigQuery query = new OpenConfigQuery();
        query.setType(OpenApiConfigEnum.OPEN_CONFIG_TYPE_WECHAT_OPEN.getCode());
        query.setSubType(WxOpenAppTypeEnum.WECHAT_OPEN_APP_TYPE_TP.getCode());
        ResponseResult<OpenConfigDTO> responseResult = globalOpenFeignClient.queryOpenConfigOne(query);
        return responseResult.getData();
    }

}
